﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

using OnlineLogCommon;
namespace OnlineLogServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SocketTcpServer server = new SocketTcpServer();
            server.AcceptCompleted += socket =>
            {
                this.Invoke(new Action(() =>
                {
                    this.richTextBox1.Text += Environment.NewLine;
                    this.richTextBox1.Text += socket.RemoteEndPoint.ToString() + " connect...";
                }));
            };
            server.ReceiveCompleted += (p, o) =>
            {
                this.Invoke(new Action(() =>
                {
                    this.richTextBox1.Text += Environment.NewLine;
                    this.richTextBox1.Text += p.ToString() + "   " + o.ToString();
                }));
            };
            server.Listen("192.168.134.196", 8081);
            //xx.EventSocektServer.Mainx();
            return;

            //Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //socket.Bind(new IPEndPoint(IPAddress.Any, 33211));
            //socket.Listen(20);
            //var socketAsyncEventArgs = new SocketAsyncEventArgs();
            //socketAsyncEventArgs.Completed += e_Completed;
            //socket.AcceptAsync(socketAsyncEventArgs);
        }

        void e_Completed(object sender, SocketAsyncEventArgs e)
        {

            Socket client = e.AcceptSocket;
            Socket server = sender as Socket;

            if (sender == null)
                return;
            //client.Available
        }

    }
    internal class ConnectInfo
    {
        public ArrayList tmpList { get; set; }
        public SocketAsyncEventArgs SendArg { get; set; }
        public SocketAsyncEventArgs ReceiveArg { get; set; }
        public Socket ServerSocket { get; set; }
    }

    public class xx
    {
        internal class ConnectInfo
        {
            public ArrayList tmpList { get; set; }
            public SocketAsyncEventArgs SendArg { get; set; }
            public SocketAsyncEventArgs ReceiveArg { get; set; }
            public Socket ServerSocket { get; set; }
        }

        internal class EventSocektServer
        {
            static Socket serverSocket;
            internal static void Mainx()
            {
                IPEndPoint serverPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8081);
                serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                serverSocket.Bind(serverPoint);
                serverSocket.Listen(10);

                Console.WriteLine("waiting for a client");
                SocketAsyncEventArgs e = new SocketAsyncEventArgs();
                e.Completed += new EventHandler<SocketAsyncEventArgs>(Accept_Completed);
                serverSocket.AcceptAsync(e);

                Console.ReadLine();
            }

            static void Accept_Completed(object sender, SocketAsyncEventArgs e)
            {
                Socket client = e.AcceptSocket;
                Socket server = sender as Socket;

                if (sender == null) return;

                SocketAsyncEventArgs sendArg = new SocketAsyncEventArgs();
                SocketAsyncEventArgs receciveArg = new SocketAsyncEventArgs();

                ConnectInfo info = new ConnectInfo();
                info.tmpList = new ArrayList();
                info.SendArg = sendArg;
                info.ReceiveArg = receciveArg;
                info.ServerSocket = server;

                byte[] sendbuffers = Encoding.ASCII.GetBytes("hello world");
                sendArg.SetBuffer(sendbuffers, 0, sendbuffers.Length);

                sendbuffers = new byte[1024];
                receciveArg.SetBuffer(sendbuffers, 0, 1024);
                receciveArg.UserToken = info;
                receciveArg.Completed += new EventHandler<SocketAsyncEventArgs>(Rececive_Completed);

                client.SendAsync(sendArg);
                client.ReceiveAsync(receciveArg);
            }

            static void Rececive_Completed(object sender, SocketAsyncEventArgs e)
            {
                ConnectInfo info = e.UserToken as ConnectInfo;
                if (info == null) return;
                Socket client = sender as Socket;
                if (client == null) return;

                if (e.SocketError == SocketError.Success)
                {
                    int rec = e.BytesTransferred;
                    //收不到数据表明客户端终止了通信
                    //关闭相关的socket和释放资源
                    if (rec == 0)
                    {
                        client.Close();
                        client.Dispose();

                        info.ReceiveArg.Dispose();
                        info.SendArg.Dispose();

                        if (info.ServerSocket != null)
                        {
                            info.ServerSocket.Close();
                            info.ServerSocket.Dispose();
                        }
                        return;
                    }

                    byte[] datas = e.Buffer;

                    //如果数据还没接收完的就把已接收的数据暂存
                    //新开辟一个足够大的buffer来接收数据
                    if (client.Available > 0)
                    {
                        for (int i = 0; i < rec; i++)
                            info.tmpList.Add(datas[i]);
                        Array.Clear(datas, 0, datas.Length);

                        datas = new byte[client.Available];
                        e.SetBuffer(datas, 0, datas.Length);
                        client.ReceiveAsync(e);
                    }
                    else
                    {
                        //检查暂存数据的ArrayList中有没有数据，有就和本次的数据合并
                        if (info.tmpList.Count > 0)
                        {
                            for (int i = 0; i < rec; i++)
                                info.tmpList.Add(datas[i]);
                            datas = info.tmpList.ToArray(typeof(byte)) as byte[];
                            rec = datas.Length;
                        }

                        //对接收的完整数据进行简单处理，回发给客户端
                        string msg = Encoding.ASCII.GetString(datas).Trim('\0');
                        if (msg.Length > 10) msg = msg.Substring(0, 10) + "...";
                        msg = string.Format("rec={0}\r\nmessage={1}", rec, msg);

                        info.SendArg.SetBuffer(Encoding.ASCII.GetBytes(msg), 0, msg.Length);
                        client.SendAsync(info.SendArg);

                        //如果buffer过大的，把它换成一个小的
                        info.tmpList.Clear();
                        if (e.Buffer.Length > 1024)
                        {
                            datas = new byte[1024];
                            e.SetBuffer(datas, 0, datas.Length);
                        }

                        //再次进行异步接收
                        client.ReceiveAsync(e);
                    }
                }
            }
        }
    }
}